<!DOCTYPE html>
<html>
  <head>
    <title>Nexys A7 ViDBo</title>
  </head>
  <body>
    <input type="button" id="btConn" name="btConn" value="Connect to board">
    <input type="button" id="uartClear" value="Clear UART output">
    <textarea id="uart" rows="10" cols="80" readonly>
    </textarea>
    <br /><br />
    <object id="nexys-svg" data="nexys-a7-export.svg" type="image/svg+xml" width="80%" height="80%">
  </body>

  <script type="text/javascript">
    var ws;
    var connected = false;
    let gpio = Object();

    function setLED(led, state) {
	led.querySelector("circle").setAttribute('opacity', state ? 1.0 : 0.1);
    }

    function doConnect(addr) {
	ws = new WebSocket(addr);

	/* Register events. */
	ws.onopen = function() {
	    connected = true;
	    document.getElementById("btConn").value = "Disconnect";

	    const nexysObject = document.getElementById('nexys-svg')
	    const nexys = nexysObject.contentDocument;

	    var msg = {gpio : {}}
	    for (let i=0;i<16;i++) {
		var sw = nexys.getElementById('SW'+i);
		const circle = sw.querySelector("circle")
		const cy = circle.getAttribute('cy')
		const is_on = cy == 900;

		circle.setAttribute('cy', is_on ? 850 : 900);

		const s = 'SW'+i;

		msg.gpio[s] = is_on;

	    }
	    ws.send(JSON.stringify(msg));
	};

	document.getElementById("btConn").onclick = function() {
	    if (connected == false) {
		doConnect("ws://localhost:8081");
	    } else {
		ws.close();
	    }
	};

	document.getElementById("uartClear").onclick = function() {
	    document.getElementById("uart").value = "";
	};

	/* Deals with messages. */
	ws.onmessage = function (evt) {
	    console.log(evt.data);
	    const json_obj = JSON.parse(evt.data);
	    if ("gpio" in json_obj) {
		for (const [key, value] of Object.entries(json_obj.gpio)) {
		    if (key in gpio) {
			/* Check if key exists */
			setLED(gpio[key],value);
		    } else {
			console.log("Missing key");
		    }
		}
	    }
	    if ("serial" in json_obj) {
		uart_area = document.getElementById("uart");
		uart_area.value += String.fromCharCode(json_obj.serial.uart);
		uart_area.scrollTop = uart_area.scrollHeight;
	    }
	};

	/* Close events. */
	ws.onclose = function(event) {
	    document.getElementById("btConn").value = "Connect to board";
	    connected = false;
	};
    }

    document.addEventListener("DOMContentLoaded", function(event) {
	document.getElementById("btConn").onclick = function() {
	    if (connected == false) {
		doConnect("ws://localhost:8081");
	    } else {
		ws.close();
	    }
	};
    });

    const nexysObject = document.getElementById('nexys-svg')
    nexysObject.addEventListener("load", function() {
	const nexys = nexysObject.contentDocument;
	for (let i=0;i<16;i++) {
	    nexys.getElementById('SW'+i).onclick = toggleSwitch;
	    gpio['LD'+i] = nexys.getElementById('LD'+i);
	}

	function toggleSwitch() {
	    const circle = this.querySelector("circle")
	    const cy = circle.getAttribute('cy')
	    const is_on = cy == 900;

	    circle.setAttribute('cy', is_on ? 850 : 900);

	    const s = new String(this.getAttribute('id'));

	    var msg = {gpio: {[s] : is_on}};

	    ws.send(JSON.stringify(msg));
	}
    },false);
  </script>
</html>
